import java.util.ArrayList;

/**
 * Desk times hold the times of availability of all immigration desks currently open in Pier C of the airport
 * This is used during the simulation to know which desks is open and to know what is the best desk to use if none is open
 * This method will create an ArrayList of LocalArrTimes of a specific size
 * 
 */

/**
 * @author hnikoue
 *
 */
public class DeskTime {
	private int indexOfLowestTime=0;
	private ArrayList<LocalArrTime> clockTimes = null;
	private int capacity;
	private LocalArrTime timeOf1stAvailability = null;
	/**
	 * Initialise all the desks at immi with a given number of desks
	 * @param nbDesks
	 */
	public DeskTime(int nbDesks){
		capacity = nbDesks;
		clockTimes = new ArrayList<LocalArrTime>(nbDesks);
	}
	
	/**
	 * Add element to a list 
	 * @return the index of the node just added
	 */
	public int add(LocalArrTime clockTime){
		int indexOfAddedNode ;
		if(clockTimes.isEmpty()){
			indexOfAddedNode = 0;
		}else{
			indexOfAddedNode = clockTimes.size();
		}
		if (indexOfAddedNode<=capacity){
			clockTimes.add(clockTime);
		}
		return indexOfAddedNode;
	}
	
	/**
	 * find1stAvailable Desk() needs to be called before calling indexOf1stAvailableDesk
	 * Find the index of the element of the list with the lowest clocktime
	 */
	public int indexOf1stAvailableDesk(){
		return indexOfLowestTime;
	}
	/**
	 * Find the element of the list with the lowest clocktime
	 * If there is one desk open, should really return the index of the open desk and a LocalArrTime of zero 
	 * Every desk is a server in my simulation
	 */
	public void find1stAvailableDesk(){
		
		if(clockTimes.size()<capacity){//not all open desks have been used
			indexOfLowestTime = clockTimes.size();//use the next available desk
			timeOf1stAvailability = null; //return null to let the user know he can use this desk to schedule the event
		}else{
			LocalArrTime refTime = clockTimes.get(0); //get 1st element of the list
			LocalArrTime testTime;
			int i;
			indexOfLowestTime = 0;
			for(i = 1; i<clockTimes.size();i++){
				testTime = clockTimes.get(i);
				if(testTime.compareTo(refTime)<0){//testTime occurs before refTime
					refTime = testTime;
					indexOfLowestTime = i;
				}
			}
			
			timeOf1stAvailability = refTime;
			
		}
	}
	/**
	 * Call find1stAvailableDesk() before this function
	 * Get the first time available  or desk available
	 * @return LocalArrTime timeOf1stAvailability
	 */
	public LocalArrTime get1stAvailableTime(){
		return timeOf1stAvailability;
	}
	/**
	 * return the element at a given index
	 * @param index
	 * @return
	 */
	public LocalArrTime getTimeAtIndex(int index){
		return clockTimes.get(index);
	}
	/**
	 * Method that look for the latest simulation time that is still earlier than the event time
	 * @param arrivalETime
	 * @return
	 */
	public int findIndexOfLastTBefore(LocalArrTime arrivalETime) {
		int index = 0;
		for(int i=1;i<clockTimes.size();i++){
			if(clockTimes.get(i).compareTo(arrivalETime)<=0){
				if(clockTimes.get(index).compareTo(arrivalETime)<0 )//we found a new maximum 
					index = i;
			}
		}
		return index;
	}
	
	/**
	 * Replace element at index
	 */
	public int replaceElement(LocalArrTime eventTime,int index){
		clockTimes.remove(index);
		return add(eventTime);
	}
	/**
	 * Add a node to the clockTime list
	 * @param newTime
	 * @param index
	 * @return
	 */
	public int setTime(LocalArrTime newTime,int index){
		clockTimes.remove(index);
		return this.add(newTime);
	}
}
